using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Security.Cryptography;
using System.Diagnostics;
using pop3dll;
using encryptit;
using SMTPdll;





namespace pop3
{
    public partial class Pop3 : Form
    {
        public string serverName = "";
        public string user = "";
        public string pass = "";
        public int portNumber = 110;
        public int msgCount = 0;
        public bool isConnected = false;
        public static bool closemeNOW = false;
        Pop3Client t;
        public string[] sizeArray;
        public bool silentDisconnect = false;
        private string replyAddress;
        Thread mailLoad;
        Thread mailStore;
        //private char[] charArray;
        //UTF8Encoding textConverterShizzle;
        encryptit._rc2 enc;

        public string header = "";
        public Pop3()
        {

            InitializeComponent();
            Clipboard.Clear();

            userTB.Text = "kwesner@charter.net";
            enc = new encryptit._rc2();




           // MessageBox.Show();


          //  MessageBox.Show(encryptedData);


        }

        private void hashCake() 
        {

            string fileName = "test.txt";  // a sample file name

            // Delete the file if it exists.
            if (System.IO.File.Exists(fileName))
            {
                System.IO.File.Delete(fileName);
            }

            // Create the file.
            using (System.IO.FileStream fs = System.IO.File.Create(fileName, 1024))
            {
                // Add some information to the file.
                byte[] info = new System.Text.UTF8Encoding(true).GetBytes("This is some text in the file.");
                fs.Write(info, 0, info.Length);
                MD5 md5 = MD5.Create();
                byte [] result = md5.ComputeHash(info,0,10);
                MessageBox.Show(result.ToString());
            }
            


        
         
        }
        private void userConnectDisplay()
        {
            if (isConnected)
                infoTB.AppendText("Successfully connected using Username: " + user + "\r\n ");
            else
            {
                infoTB.AppendText("Could not connect using Username: " + user + "\r\n ");
            }
        
        }
        private void connectB_Click(object sender, EventArgs e)
        {
            int type = 0;
            const int maxTypes = 2;

            string [] usernames = new string [maxTypes];
            usernames[0] = userTB.Text.Substring(0, userTB.Text.IndexOf('@'));
            usernames[1] = userTB.Text;
            
            while((type < maxTypes) && !isConnected)
            {
                connectShizzle(usernames[type++], userTB.Text.Substring(userTB.Text.IndexOf('@') + 1), passwordTB.Text);
            }
             if (!isConnected)
                    infoTB.AppendText("Your username or password has been either entered incorrectly, or there is an issue.");

        }
        /// <summary>
        /// Yeah we were thinking what when we named this ? 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="server"></param>
        /// <param name="pass"></param>
        /// <returns></returns>
        private bool connectShizzle(string user, string server, string pass) 
        {
            try
            {
                if (!isConnected)
                {



                    //infoTB.AppendText(user + "\r\n");
                    serverName = server;

                    if (serverName.Equals("utm.edu"))
                    {
                        serverName = "xmail.utm.edu";
                    }
                    else
                    {
                        string mail = "mail.";
                        serverName = mail + serverName;

                    }



                    //maybe we shouldn't pass around an entire class full of info?
                    t = new Pop3Client(user, serverName, pass);
                    isConnected = t.connect();
                    userConnectDisplay();
                    
                    
                    if (isConnected)
                    {
                        closemeNOW = false;
                        infoTB.AppendText(t.resultLines);
                        msgCntL.Text = "Message Count: ";
                        if (!(t.getCount() == -1))
                        {
                            mailLister(t);
                        }
                        else
                        {
                            infoTB.AppendText(t.errorMsgs);

                        }//if for the getcount() error

                    }
                    else
                    {

                        infoTB.AppendText(t.errorMsgs);

                    }//if for the connection error

                }//if to prevent multiple logins
                
               // writeTo(encryptZorz(pass));
                
               // MessageBox.Show(decryptZorz(readFrom(userTB.Text)));
                
                return isConnected;
            }
            catch (CryptographicException cexc)
            {
                infoTB.AppendText("Exception in Decryption " + cexc.Message);
                return isConnected;
            }
            catch (Exception exc)
            {
                infoTB.AppendText("Exception in connection form1.cs " + exc.Message);
                return false;

            }

        
        
        }
        
        delegate void mylinkupdater(int pos, Pop3Client.MessageHeader h);
        private void updateList(int pos ,Pop3Client.MessageHeader h) {

            if (this.msgHeaderView.InvokeRequired)
            {
                mylinkupdater a = new mylinkupdater(updateList);
                this.Invoke(a, new object[] { pos,h });
            }
            else
            {
                h.size = sizeArray[pos + 1].Substring(sizeArray[pos + 1].IndexOf(' ') + 1);
                ListViewItem headerItem = this.msgHeaderView.Items.Add((pos + 1).ToString());
                headerItem.SubItems.Add(h.date);
                headerItem.SubItems.Add(h.from);
                headerItem.SubItems.Add(h.subject);
                headerItem.SubItems.Add(h.size);
                msgHeaderView.Update();
                
            }
        
        }

        private void msgHeader(int pos,int realPos,Pop3Client z)
        {
            Pop3Client.MessageHeader h = z.getMessageHeader(realPos);
            updateList(pos, h);
                
        }
        private void disconnectB_Click(object sender, EventArgs e)
        {
            if (isConnected)
            { 

                t.disconnect();
                //infoTB.Text  = t.resultLines;
                isConnected = false;
                closemeNOW = !isConnected;
                if(File.Exists("email.txt"))
                {
                    File.Delete(@"email.txt");
                }

                if (!silentDisconnect)
                {
                    msgHeaderView.Items.Clear();
                    msgTB.Clear();
                    passwordTB.Clear();
                    msgNumTB.Clear();
                    msgCntL.Text = "Message Count: 0";
                    infoTB.Clear();
                    infoTB.AppendText(t.resultLines);
                    msgPB.Value = 0;
                    progressL.Text = "";
                }
            }
            
        }

        private void getMsgB_Click(object sender, EventArgs e)
        {
            if (!mailLoad.IsAlive && !mailStore.IsAlive)
            {
                if (msgHeaderView.SelectedIndices.Count > 0)
                {

                    for (int i = 0; i < msgHeaderView.SelectedIndices.Count; i++)
                    {

                        msgNumTB.Text = msgHeaderView.Items[msgHeaderView.SelectedIndices[i]].Text;
                        msgTB.Text = t.getMessage(int.Parse(msgNumTB.Text));
                        showMailViewer(msgTB.Text, msgNumTB.Text);
                    }




                    msgHeaderView.SelectedItems.Clear();
                }
                else
                {
                    if (isConnected && msgNumTB.Text != "")
                    {


                        msgTB.Text = t.getMessage(int.Parse(msgNumTB.Text));
                        showMailViewer(msgTB.Text, msgNumTB.Text);
                    }
                }


            }
            else
            {
                msgTB.Text = "Please be patient while the messages are loading....\r\n";
            }
        }
        //public string getReply { get { return replyAddress; } }
        private void showMailViewer(string text,string msgnum) 
        {
            msgViewer msgView = new msgViewer();
            msgView.replyAddress = replyAddress;
                msgView.mListView = msgHeaderView;
                msgView.j = t;
                msgView.msgNum = int.Parse(msgnum);
                msgView.setText(int.Parse(msgnum));
                msgView.fromTB.Show();
                msgView.fromL.Show();
                msgView.subjectTB.Show();
                msgView.subjectL.Show();


            msgView.Show();
     
        }

        private void msgTopTB_Click(object sender, EventArgs e)
        {
            if (!mailLoad.IsAlive && !mailStore.IsAlive)
            {
                if (isConnected && msgNumTB.Text != "")
                {
                    msgTB.Text = t.getMessageTop(int.Parse(msgNumTB.Text));
                }
            }
            else
            {
                msgTB.Text = "Please be patient while the messages are loading....\r\n";
            }
        }

        private void deleteB_Click(object sender, EventArgs e)
        {
            if (isConnected && msgNumTB.Text != "")
            {
                for (int i = 0; i < msgHeaderView.SelectedIndices.Count; i++)
                {

                    msgNumTB.Text = msgHeaderView.Items[msgHeaderView.SelectedIndices[i]].Text;

                    if (t.deleteMessage(int.Parse(msgNumTB.Text)))
                        infoTB.AppendText("Message " + int.Parse(msgNumTB.Text) + " was deleted.\r\n");
                    else
                        infoTB.AppendText("Message " + int.Parse(msgNumTB.Text) + " was NOT deleted.\r\n");
                } 


                
            }
        }

        private void newMail_Tick(object sender, EventArgs e)
        {
            if (isConnected) 
            {
                Pop3Client w = new Pop3Client(userTB.Text, serverName, passwordTB.Text);
                w.connect();
                int temp = w.getCount();
                //MessageBox.Show("temp = " + temp);
                if (temp > msgCount)
                {
                    mailLister(w);
                    infoTB.AppendText("New MAIL!!! Woot!!\r\n");
                    FileInfo sound2play = new FileInfo("ecky.wav");
                    MessageBox.Show(sound2play.FullName);
                    //System.Media.SoundPlayer s = new System.Media.SoundPlayer(sound2play.FullName);
                   // s.Play();
                    silentDisconnect = true;
                    t = w;
                    silentDisconnect = false;

                }

            }
        }

        private void mailLister(Pop3Client y) 
        {
            string mCount = y.getCount().ToString();
            msgCount = int.Parse(mCount);
            
            sizeArray = (y.resultLines.Split('\r'));
            msgCntL.Text = "Message Count: ";
            msgCntL.Text += mCount;
            if (msgCount > 100)
            {
                msgPB.Step = msgCount / 10;
            }
            else
            {
                msgPB.Step = msgCount / 5;
            }

            msgPB.Value = 0;

            progressL.Text = "Getting Header for Message : 0 of "  +  msgCntL.Text;
            
            msgHeaderView.Items.Clear();

 
            mailStore = new Thread(delegate()
            {
                if(File.Exists(@"email.txt"))
                       File.Delete(@"email.txt");
                FileStream fstream = new FileStream(@"email.txt", FileMode.Append);
                StreamWriter streamWriter = new StreamWriter(fstream);
                lock (y)
                {
                    updatePB(0);
                    for (int i = 1; i <= int.Parse(mCount); i++)
                    {
                        streamWriter.WriteLine("BOE: " + i.ToString());
                        streamWriter.WriteLine(t.storeMessage(i));
                        streamWriter.WriteLine("\r\nEOE:\r\n");
                        float currentNumPB = (i / (float)msgCount) * 100;
                        int currentIntPB = (int)currentNumPB;
                        //MessageBox.Show(currentIntPB.ToString());
                        updatePB(currentIntPB);
                        progressL.Text = "Storing Message Number : " + i + " of " + msgCntL.Text;
                    }
                    MessageBox.Show("All emails successfully stored!");
                }
                streamWriter.Close();
                fstream.Close();

                mailLoad = new Thread(delegate()
                {
                    lock (y)
                    {

                        for (int i = 1; i <= int.Parse(mCount); i++)
                        {
                            msgHeader(i - 1, i, t);
                            float currentNumPB = (i / (float)msgCount) * 100;
                            int currentIntPB = (int)currentNumPB;
                            //MessageBox.Show(currentIntPB.ToString());
                            updatePB(currentIntPB);
                            progressL.Text = "Getting Header for Message : " + i + " of " + msgCntL.Text;
                        }

                    }
                });

                mailLoad.Start();
            });
            mailStore.Start();


 

        
        
        }
        delegate void myPBupdater(int val);
        private void updatePB(int val)
        {

            if (this.msgPB.ProgressBar.InvokeRequired)
            {
                myPBupdater a = new myPBupdater(updatePB);
                this.Invoke(a, new object[] { val });
            }
            else
            {
                this.msgPB.Value = val;
            }
        }
        /*delegate void myPBLupdater(int val);
        private void updatePBL(int val)
        {

            if (this.progressL.)
            {
                myPBupdater a = new myPBupdater(updatePB);
                this.Invoke(a, new object[] { val });
            }
            else
            {
                this.msgPB.Value = val;
            }
        }*/
        private void sendB_Click(object sender, EventArgs e)
        {
            SMTPviewer sendClient = new SMTPviewer(replyAddress);
            sendClient.Show();
        }


        private void setMsgNumB_Click(object sender, EventArgs e)
        {
                msgNumTB.Text = msgHeaderView.SelectedItems[0].Text;
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 m = new AboutBox1();
            m.Show();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process docEdit = new Process();
            docEdit.StartInfo.FileName = "notepad.exe";
            docEdit.StartInfo.Arguments = "newDocument.doc";
            docEdit.Start();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            openFileDialog.InitialDirectory = @"C:\";
            openFileDialog.Title = "Select File To Open.";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {

                DialogResult nobba = MessageBox.Show("Open file? \r\n" + openFileDialog.FileName,
                    "You really want to open this?",
                    MessageBoxButtons.OKCancel);
                if (nobba.Equals(DialogResult.OK))
                {

                    System.Diagnostics.Process.Start(openFileDialog.FileName);

                   
                }
                else
                {
                    MessageBox.Show("Fine then....I didn't open the file!");
                }

            }
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (msgTB.SelectionLength > 0)
            {

                // Copy the selected text to the Clipboard.
                msgTB.Copy();
            }
            else
            {
                infoTB.Text += "There is nothing to COPY from the current message.\r\n";
            }
          
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (msgTB.SelectionLength > 0)
            {

                // Copy the selected text to the Clipboard.
                msgTB.Cut();
            }
            else
            {
                infoTB.Text += "There is nothing to CUT from the current message.\r\n";
            }
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            infoTB.Paste();
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            msgTB.SelectAll();
        }

        private void searchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //MessageBox.Show(msgTB.Text.Length.ToString());
            if (msgTB.Text.Length > 0)
            {
                searchForm j = new searchForm(msgTB.Text);
                Thread searcher = new Thread(delegate() { j.ShowDialog(); });
                searcher.Start();
                
            }
            else 
            {
                infoTB.Text += "There is no message opened to search in the message box below.";
            }

        }

        private byte[] encryptZorz(string message)
        {
            
            
             
            //textConverterShizzle = new UTF8Encoding();
            //charArray = textConverterShizzle.GetChars(encryptedmsg);
            return enc.doEncrypt(message);

        }

        private string decryptZorz(byte[] kaplaa)
        {
            

            return enc.decrypt(kaplaa);
             
        }

        private void writeTo(byte[] eMsg)
        {

            System.IO.FileStream fStream = new FileStream(userTB.Text, FileMode.Open);
            //StreamWriter sWriter = new StreamWriter(fStream);
            
            fStream.Write(eMsg, 0,  eMsg.Length-1);
            
            fStream.Flush();
            fStream.Close();
        }

        private byte[] readFrom(string userName)
        {
            //System.IO.FileStream rStream = new FileStream(userName, FileMode.Open);
            FileStream rStream = File.OpenRead(userName);
            StreamReader strReader = new StreamReader(rStream);
            string temp = strReader.ReadLine();
            
            
            //temp = temp.Substring(0, temp.IndexOf('\r'));
            MessageBox.Show("This is temp: " + temp);
            strReader.Close();
            rStream.Close();
            UTF8Encoding textConverter = new UTF8Encoding();
            byte[] returnMe = textConverter.GetBytes(temp);
            return returnMe;
        }


    }



 

}